Skip to content

WIP: CPU network SoA dual-write (not for merge) - #3822

Draft
nrnhines wants to merge 20 commits into
masterfrom
local/cpu-network-soa
Draft

WIP: CPU network SoA dual-write (not for merge)#3822
nrnhines wants to merge 20 commits into
masterfrom
local/cpu-network-soa

Conversation

@nrnhines

Copy link
Copy Markdown
Member

Status: Work in progress — do not merge to master

Exploratory stack for CoreNEURON-shaped network data on the NEURON CPU side. Intended as a durable review/reference branch, not a landable feature PR.

Planned follow-on branch (later): hines-grok/cpu-net-soa-heap-free (or similar), forked from this work after dual-write+sort, to drop long-lived NetCon::weight_ under a defined ABI plan.

GPU native (later, undetermined order relative to master): spike queue + threshold → net_send buffer on GPU; NET_RECEIVE net_send on GPU; ARTIFICIAL_CELL net_send stays CPU; distribute via net_receive buffer. Whether heap-free lands on master before that GPU track is undecided.

What this PR contains

  • Phases 0–4 dual-write: PointProcess, Weight, NetCon, PreSyn SoA; SelfEvent weight_index
  • Network containers in nrn_ensure_model_data_are_sorted (thread packing, weight-block contiguity, fanout rebuild)
  • SaveState / BBSaveState dual-write (SoA values + NetCon-index SelfEvent identity)
  • Developer docs: doc/network-soa/ (topology, heap policy, sort) + GROK-NETWORK-SOA.md + doc/network-soa-phase0.md

Explicitly not in this PR

  • Freeing NetCon::weight_ (nocmodl still needs long-lived MOD scratch for net_send(..., _w) / FOR_NETCONS / INITIAL)
  • GPU net buffers / native GPU network
  • Thin remote InputPreSyn / gid→fanout redesign
  • Performance claims vs NEURON 8.2.7 or CoreNEURON (benchmark plan to be separate)

Docs for reviewers

Start at doc/network-soa/README.md.

Test plan

  • Full ctest -j 8 on author machine (post-regression fixes)
  • CI (when draft is marked ready or CI runs on draft)
  • Future: ringtest / space / time vs NEURON 8.2.7, this branch, CoreNEURON (linux + Apple M1)

nrnhines added 15 commits July 8, 2026 18:00
Documents the decision to pause GPU network buffers until CPU network
SoA adoption. Provides agent rules, session starting prompt, and Phase 0
design checklist for local/cpu-network-soa branched from master.
Expand doc/network-soa-phase0.md into the authoritative field-tag, handle,
thread-slice, sidecar, and invalidation spec. Add neuron::container::network
PointProcess and Weight soa storages on Model (Node-style handles), wire
find_container_info/unsorted callbacks, and unit-test that handles survive
permutation.
Add §5.4.1 (target_/src_ as indices/handles, not data_handle) and
§5.5.1 (InputPreSyn deferred; thin gid→fanout after cpu-net-soa).
Embed PointProcess::owning_handle on Point_process and sync Instance/
MechType/ThreadId when prop or _vnt changes. NetCon allocates parallel
Weight SoA rows (heap weight_ stays delivery primary). Unit tests cover
dual-write helpers and PP shell lifetime.
Add network::NetCon storage (Target, WeightIndex, WeightCount, Delay,
Active, SrcPreSyn) on Model. NetCon owns an SoA row and syncs fields on
create/update. HOC weight() steers into Weight SoA data_handles; deliver
mirrors SoA↔heap around pnt_receive so NET_RECEIVE still sees double*.
Add network::PreSyn storage on Model and embed owning handles on PreSyn.
Rebuild a global NetCon* fanout order from dil_ (CoreNEURON-shaped ranges);
send/deliver/fanout iterate that order with dil_ fallback. NetCon::SrcPreSyn
points at the source PreSyn SoA row.
SelfEvent records Weight SoA base index and PointProcess row; net_send
resolves index from NetCon. Delivery uses nrn_pnt_receive_by_weight_index
(M2: SoA→heap→MOD pnt_receive→heap→SoA). NetCon::deliver shares that path.
…ght wipe

Document Phases 0–4 status and known gaps in GROK-NETWORK-SOA.md. Rebuild
PreSyn fanout at NetCvode::init_events (not only on first spike). Stop
soa_sync from copying heap weights over SoA (HOC weight writes). Add
pytest/ctest network_soa_delivery gate for NetStim→ExpSyn.
MOD/nrnivmodl builds only see build/include. Embedding PointProcess
owning_handle forced network/model_data headers that are not installed
there, breaking demo release compiles. Store a non-owning _soa_id on
Point_process; own the SoA row via a map in point.cpp. Add
point_process_access.hpp / nrn_point_process_soa_row for library code.
HOC weight[] is SoA-primary; pnt_receive_init and FOR_NETCONS mutate the
heap. Sync SoA↔heap around INITIAL, and for FOR_NETCONS targets sync all
NetCons sharing the target (including WatchCondition flag delivery).
Fixes hoctests::test_netrec_init_py and external_nrntest FOR_NETCONS/stdp1.
…eliver

Include PointProcess, Weight, NetCon, and PreSyn containers in
nrn_ensure_model_data_are_sorted (thread partition, weight-block repack,
fanout rebuild, cache offsets). On NetCon deliver without FOR_NETCONS,
pass a temporary buffer into pnt_receive instead of the long-lived weight_
heap so SoA stays the source of truth while the heap remains for SaveState
and FOR_NETCONS.
Save NetCon weights from Weight SoA (HOC-primary) and restore into both
heap and SoA so materialize-on-deliver matches SaveState. Resolve SelfEvent
ownership via NetCon object index and weight_index2netcon when the heap
pointer is absent; index2netcon maps all NetCons by HOC index.
Materialize Weight SoA into the heap before BBSaveState weight IO and
mirror heap back to SoA after restore. Match SelfEvents to target NetCons
by heap base or weight_index, and rebind both fields from the DEList
ncindex on restore (same dual-write policy as SaveState).
sort_network_data must resolve HOC point-process objects via
ob2pntproc_0 (dataspace), not this_pointer. NetCon deliver must pass the
long-lived weight_ heap into pnt_receive so MOD net_send(..., _w)
preserves SelfEvent identity for SaveState; resolve owner by weight_index
when needed. Softens SelfEvent savestate_write when no NetCon is found.
Add doc/network-soa/ with L0 README, topology (fanout authority, CoreNEURON
mapping), dual-write/heap roadmap, and sort packing. Point GROK handoff at
the layered map and correct stale short-lived-materialize status text.
WHEN("A random reverse-permutation is applied") {
std::vector<std::size_t> perm(n);
std::iota(perm.begin(), perm.end(), 0);
std::mt19937 g{42};
std::vector<std::size_t> perm(n);
std::iota(perm.begin(), perm.end(), 0);
std::mt19937 g{42};
std::shuffle(perm.begin(), perm.end(), g);
@github-actions

Copy link
Copy Markdown
Contributor

✔️ 415a51f -> artifacts URL

@azure-pipelines

Copy link
Copy Markdown

✔️ 415a51f -> Azure artifacts URL

nrnhines added 2 commits July 22, 2026 21:11
Sync Weight SoA when exporting NetCon weights to CoreNEURON and when
returning weights after a CoreNEURON run (HOC weight[] is SoA-primary).
Apply black/clang-format line-wrap fixes for network SoA tests. Merge
with master already on branch for formatting toolchain updates.
@azure-pipelines

Copy link
Copy Markdown

✔️ d8911a3 -> Azure artifacts URL

@github-actions

Copy link
Copy Markdown
Contributor

✔️ d8911a3 -> artifacts URL

SelfEvent from mech INITIAL often has nullptr weight; still route through
nrn_pnt_receive_by_weight_index so FOR_NETCONS heap mutations sync to SoA.
Apply ninja format-pr clang-format fixes for network SoA sources.
@azure-pipelines

Copy link
Copy Markdown

✔️ 15b4db3 -> Azure artifacts URL

@github-actions

Copy link
Copy Markdown
Contributor

✔️ 15b4db3 -> artifacts URL

ASan CI: nrn_point_process_soa_sync during free_one_point/relocate read
freed Prop or dangling state. Stop syncing on free (SoA row released in
~Point_process); harden sync to verify prop still owns this pnt and that
_vnt is a live NrnThread.

NetCon factory wrote magnitude only to weight_ heap; HOC weight[] reads
SoA and init_events soa_to_heap wiped the value (0.0 != 0.1). Mirror
magnitude into Weight SoA after construction.
@azure-pipelines

Copy link
Copy Markdown

✔️ d55851a -> Azure artifacts URL

@github-actions

Copy link
Copy Markdown
Contributor

✔️ d55851a -> artifacts URL

Do not invent a short-lived weight buffer when weight_index < 0
(flag-only / INITIAL net_send); MOD may net_send that pointer and
corrupt later queue / BBSaveState handling. Skip NET_RECEIVE INITIAL
for NetCons whose target Prop is already freed.
@sonarqubecloud

Copy link
Copy Markdown

@azure-pipelines

Copy link
Copy Markdown

✔️ 77297b9 -> Azure artifacts URL

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.20663% with 121 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.62%. Comparing base (0c9dab0) to head (77297b9).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/nrncvode/netcvode.cpp 75.40% 60 Missing ⚠️
src/nrncvode/network_soa_sort.cpp 93.98% 11 Missing ⚠️
src/nrniv/bbsavestate.cpp 67.64% 11 Missing ⚠️
src/nrnoc/container.cpp 61.90% 8 Missing ⚠️
test/unit_tests/container/network.cpp 97.93% 6 Missing ⚠️
src/neuron/container/memory_usage.hpp 66.66% 4 Missing ⚠️
src/neuron/container/network/netcon.hpp 85.71% 4 Missing ⚠️
src/nrniv/savstate.cpp 76.47% 4 Missing ⚠️
src/nrnoc/point.cpp 90.90% 3 Missing ⚠️
src/neuron/container/network/point_process.hpp 87.50% 2 Missing ⚠️
... and 4 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3822      +/-   ##
==========================================
+ Coverage   68.48%   68.62%   +0.14%     
==========================================
  Files         691      700       +9     
  Lines      111413   112418    +1005     
==========================================
+ Hits        76301    77151     +850     
- Misses      35112    35267     +155     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

Copy link
Copy Markdown
Contributor

✔️ 77297b9 -> artifacts URL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants